package com.example.day3.stream;

import java.util.stream.Stream;

/*
    化简：两两合并,只剩一个
    适合：最大值、最小值、求和、求个数...
        .reduce((p, x) -> r)        p 上次的合并结果, x 当前元素, r 本次合并结果
        .reduce(init, (p, x) -> r)
        .reduce(init, (p, x) -> r, (r1, r2) -> r)
 */
public class C10ReduceTest {
    public static void main(String[] args) {
        Stream<Hero> stream = Stream.of(
                new Hero("令狐冲", 90),
                new Hero("风清扬", 98),
                new Hero("独孤求败", 100),
                new Hero("方证", 92),
                new Hero("东方不败", 98),
                new Hero("冲虚", 90),
                new Hero("向问天", 88),
                new Hero("任我行", 92),
                new Hero("不戒", 88)
        );
        // 1) 求武力最高的 hero
        // 第一种reduce方法,会返回一个 Optional 对象,用来预防流中没有数据并且不想返回null的情况
        // Optional<Hero> result = stream.reduce((h1, h2) -> h1.strength() > h2.strength() ? h1 : h2);
        // 第二种reduce方法,给定一个初始值,如果流中没有数据,则返回初始值
        // Hero hero = stream.reduce(new Hero("无", -0), (h1, h2) -> h1.strength() > h2.strength() ? h1 : h2);

        // 2) 求高手总数
        // System.out.println(stream.map(h -> 1).reduce((x, y) -> x + y));
        // 使用方法引用简化
        // System.out.println(stream.map(h -> 1).reduce(Integer::sum));

        // 常见方法 max min sun count average
        // System.out.println(stream.count()); // 统计数量
        // 因为目前一个对象流,所以我们需要手动的指定比较规则
        // System.out.println(stream.max(Comparator.comparingInt(Hero::strength))); // 找到武力值最高的一个
        // System.out.println(stream.min(Comparator.comparingInt(Hero::strength))); // 找到武力值最低的一个
        // 因为现在是一个对象流,所以我们需要把流中的数据转换成 int 流
        // System.out.println(stream.mapToInt(Hero::strength).sum()); // 求和
        System.out.println(stream.mapToInt(Hero::strength).average()); // 求平均
    }

    record Hero(String name, int strength) {

    }
}
